﻿package com.ui.cell
{
	import com.ui.controls.Icon;
	import com.ui.controls.Label;
	import com.ui.core.Align;
	import com.ui.core.PhaseState;
	import com.ui.core.ScaleMode;
	import com.ui.core.UIComponent;
	import com.ui.data.LabelData;
	import com.ui.layout.GLayout;
	import com.ui.manager.UIManager;
	import com.utils.ColorMatrixUtil;

	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.filters.ColorMatrixFilter;
	import flash.utils.Timer;

	/**
	 * Game Cell
	 * 
	 * @author Cafe
	 * @version 20100730
	 */
	public class Cell extends UIComponent
	{
		public static const SELECT : String = "select";
		public static const SINGLE_CLICK : String = "singleClick";
		public static const DOUBLE_CLICK : String = "doubleClick";
		protected var _data : CellData;
		protected var _upSkin : DisplayObject;
		protected var _overSkin : DisplayObject;
		protected var _selected_upSkin : DisplayObject;
		protected var _selected_overSkin : DisplayObject;
		protected var _disabledSkin : DisplayObject;
		protected var _lockIcon : Icon;
		protected var _key_lb : Label;
		protected var _selected : Boolean = false;
		protected var _current : DisplayObject;
		protected var _timer : Timer;
		protected var _count : int;
		protected var _ctrlKey : Boolean = false;
		protected var _shiftKey : Boolean = false;
		protected var _phase : int = PhaseState.UP;
		protected var _rollOver : Boolean = false;
		protected var _mouseX : int;
		protected var _mouseY : int;
		protected static var colorMatrixFilter:ColorMatrixFilter = new ColorMatrixFilter( ColorMatrixUtil.GRAY );

		override protected function create() : void
		{
			_upSkin = UIManager.getUI( _data.upAsset );
			_current = _upSkin;
			addChild( _current );
			if (_data.lockIconData)
			{
				_data.lockIconData.parent = this;
				_lockIcon = new Icon( _data.lockIconData );
			}
			addKeyLabel();
			switch(_data.scaleMode)
			{
				case ScaleMode.SCALE_WIDTH:
					_height = _upSkin.height;
					break;
				case ScaleMode.SCALE_NONE:
					_width = _upSkin.width;
					_height = _upSkin.height;
					break;
			}
		}

		protected function addKeyLabel() : void
		{
			if (_data.hotKey == null) return;
			var data : LabelData = new LabelData();
			data.text = _data.hotKey;
			data.textColor = 0xFFFFFF;
			data.textFieldFilters = UIManager.getEdgeFilters( 0x000000, 0.9 );
			data.align = new Align( 2, -1, 1 );
			data.mouseEnabled = false;
			_key_lb = new Label( data );
			addChild( _key_lb );
		}

		override protected function layout() : void
		{
			_upSkin.width = _width;
			_upSkin.height = _height;
			if (_overSkin != null)
			{
				_overSkin.width = _width;
				_overSkin.height = _height;
			}
			if (_selected_upSkin != null)
			{
				_selected_upSkin.width = _width;
				_selected_upSkin.height = _height;
			}
			if (_selected_overSkin != null)
			{
				_selected_overSkin.width = _width;
				_selected_overSkin.height = _height;
			}
			if (_disabledSkin != null)
			{
				_disabledSkin.width = _width;
				_disabledSkin.height = _height;
			}
			GLayout.layout( _key_lb );
		}

		override protected function onEnabled() : void
		{
			if (!_enabled && _timer && _timer.running) _timer.stop();
			viewSkin();
		}

		override protected function onShow() : void
		{
			if (_data.allowDoubleClick)
			{
				addEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler );
				addEventListener( MouseEvent.CLICK, clickHandler, false, 100 );
			}
			else
			{
				addEventListener( MouseEvent.CLICK, singleClickHandler );
			}
			addEventListener( MouseEvent.ROLL_OVER, rollOverHandler );
			addEventListener( MouseEvent.ROLL_OUT, rollOutHandler );
			addEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
		}

		override protected function onHide() : void
		{
			if (_data.allowDoubleClick)
			{
				if (_timer)
				{
					if (_timer.running) _timer.stop();
				}
				removeEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler );
				removeEventListener( MouseEvent.CLICK, clickHandler );
			}
			else
			{
				removeEventListener( MouseEvent.CLICK, singleClickHandler );
			}
			removeEventListener( MouseEvent.ROLL_OVER, rollOverHandler );
			removeEventListener( MouseEvent.ROLL_OUT, rollOutHandler );
			removeEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
			_phase = PhaseState.UP;
			viewSkin();
		}

		protected function viewSkin() : void
		{
			if (!_enabled)
			{
				if (selected)
				{
				}
				else
				{
					if (_disabledSkin == null)
					{
						_disabledSkin = UIManager.getUI( _data.disabledAsset );
						if (_disabledSkin)
						{
							_disabledSkin.width = _width;
							_disabledSkin.height = _height;
						}
					}
					_current = swap( _current, _disabledSkin );
				}
			}
			else if (_phase == PhaseState.UP)
			{
				if (_selected)
				{
					if (_selected_upSkin == null)
					{
						_selected_upSkin = UIManager.getUI( _data.selected_upAsset );
						if (_selected_upSkin)
						{
							_selected_upSkin.width = _width;
							_selected_upSkin.height = _height;
						}
					}
					_current = swap( _current, _selected_upSkin );
				}
				else
				{
					_current = swap( _current, _upSkin );
				}
			}
			else if (_phase == PhaseState.OVER)
			{
				if (_selected)
				{
					if (_selected_overSkin == null)
					{
						_selected_overSkin = UIManager.getUI( _data.selected_overAsset );
						if (_selected_overSkin)
						{
							_selected_overSkin.width = _width;
							_selected_overSkin.height = _height;
						}
					}
					_current = swap( _current, _selected_overSkin );
				}
				else
				{
					if (_overSkin == null)
					{
						_overSkin = UIManager.getUI( _data.overAsset );
						if (_overSkin)
						{
							_overSkin.width = _width;
							_overSkin.height = _height;
						}
					}
					_current = swap( _current, _overSkin );
				}
			}
			else if (_phase == PhaseState.DOWN)
			{
				if (_selected)
				{
				}
				else
				{
				}
			}
		}

		protected function rollOverHandler( event : MouseEvent ) : void
		{
			if (!_enabled) return;
			_count = 0;
			if (_timer == null)
			{
				_timer = new Timer( 150, 1 );
				_timer.addEventListener( TimerEvent.TIMER, timerHandler );
			}
			_rollOver = true;
			_phase = PhaseState.OVER;
			viewSkin();
		}

		protected function rollOutHandler( event : MouseEvent ) : void
		{
			if (!_enabled) return;
			if (_timer)
			{
				if (_timer.running) _timer.stop();
			}
			_rollOver = false;
			_phase = PhaseState.UP;
			viewSkin();
		}

		protected function mouseUpHandler( event : MouseEvent ) : void
		{
			if (!_enabled) return;
			_mouseX = UIManager.root.mouseX;
			_mouseY = UIManager.root.mouseY;
			_phase = (_rollOver ? PhaseState.OVER : PhaseState.UP);
			viewSkin();
		}

		protected function timerHandler( event : TimerEvent ) : void
		{
			_count = 0;
			onSingleClick();
		}

		protected function mouseDownHandler( event : MouseEvent ) : void
		{
			_mouseX = UIManager.root.mouseX;
			// +UIManager.stageOffset.x;
			_mouseY = UIManager.root.mouseY;
			// +UIManager.stageOffset.y;
			if (!_enabled) return;
			if (_timer && _timer.running) _timer.stop();
		}

		protected function clickHandler( event : MouseEvent ) : void
		{
			_ctrlKey = event.ctrlKey;
			_shiftKey = event.shiftKey;
			if (_count == 1)
			{
				if (_timer && _timer.running)
				{
					_timer.stop();
				}
				_count = 0;
				onDoubleClick();
			}
			else
			{
				_count++;
				if (_timer)
				{
					_timer.reset();
					_timer.start();
				}
			}
		}

		protected function singleClickHandler( event : MouseEvent ) : void
		{
			_ctrlKey = event.ctrlKey;
			_shiftKey = event.shiftKey;
			onSingleClick();
		}

		protected function onSingleClick() : void
		{
			if (_data.allowSelect && _data.clickSelect)
			{
				if (!_selected)
				{
					selected = true;
				}
			}
			dispatchEvent( new Event( Cell.SINGLE_CLICK ) );
		}

		protected function onDoubleClick() : void
		{
			if (_data.allowSelect && _data.clickSelect)
			{
				if (!_selected)
				{
					selected = true;
				}
			}
			dispatchEvent( new Event( Cell.DOUBLE_CLICK ) );
		}

		protected function onSelected() : void
		{
			// this is abstract function
		}

		public function Cell( data : CellData )
		{
			_data = data;
			super( data );
			lock = _data.lock;
		}

		public function set selected( value : Boolean ) : void
		{
			if (_selected == value) return;
			_selected = value;
			viewSkin();
			onSelected();
			if (_selected) dispatchEvent( new Event( Cell.SELECT ) );
		}

		public function get selected() : Boolean
		{
			return _selected;
		}

		public function set lock( value : Boolean ) : void
		{
			if (value)
			{
				_lockIcon.show();
				GLayout.layout( _lockIcon );
			}
			else
			{
				_lockIcon.hide();
			}
		}

		public function get ctrlKey() : Boolean
		{
			return _ctrlKey;
		}

		public function get shiftKey() : Boolean
		{
			return _shiftKey;
		}

		public function get data() : CellData
		{
			return _data;
		}

		public function clone() : Cell
		{
			var cell : Cell = new Cell( _data.clone() );
			cell.source = _source;
			return cell;
		}
	}
}
